﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Configuration;

using ClientLib;

namespace JigsawAdmin.SubForms.Security
{
    public partial class Users : Form
    {
        ClientUtil _cutil;
        TreeNode _selectednode;
        JsvcEnc.EncSoapXml xmlsvc;
        ContextMenu ctxmUser;

        public Users(ClientUtil cUtil)
        {
            InitializeComponent();

            _cutil = cUtil;
            xmlsvc = new JsvcEnc.EncSoapXml();
            xmlsvc.Url = _cutil.ServiceURL;

            // set up folder images for treeview
            ImageList apiTreeList = new ImageList();
            apiTreeList.Images.Add(Image.FromFile("../../Images/Folder.png"));
            apiTreeList.Images.Add(Image.FromFile("../../Images/Node.png"));
            apiTreeList.Images.Add(Image.FromFile("../../Images/Rootfolder.png"));

            ctxmUser = new ContextMenu();
            MenuItem mnuRoles = new MenuItem("User Roles");
            MenuItem mnuReset = new MenuItem("Password Reset");
            ctxmUser.MenuItems.Add(mnuRoles);
            ctxmUser.MenuItems.Add(mnuReset);
            mnuRoles.Click +=new EventHandler(mnuRoles_Click);
            mnuReset.Click +=new EventHandler(mnuReset_Click);

            trvUsers.ImageList = apiTreeList;
            trvUsers.ImageIndex = 0;
            trvUsers.SelectedImageIndex = 1;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuRoles_Click(object sender, EventArgs e)
        {
            UserTreeNode selectedTag = (UserTreeNode)_selectednode.Tag;
            string userID = selectedTag.GID;

            // show roles form for selected user
            UserRoles userroles = new UserRoles(_cutil, userID);
            userroles.Show();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuReset_Click(object sender, EventArgs e)
        {
            DialogResult result;
            result = MessageBox.Show("Are you sure you want to reset the user password?", "Password Reset", MessageBoxButtons.YesNo);

            if (result == DialogResult.Yes)
            {
                UserTreeNode selectedTag = (UserTreeNode)_selectednode.Tag;
                string userID = selectedTag.GID;

                // reset the password (to standard value) for selected userid

                MessageBox.Show("Password has been reset.", "Reset Confirmation");
            }
        }

        /// <summary>
        /// initialize form data
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Users_Shown(object sender, EventArgs e)
        {
            try
            {
                PopulateUserTree();
            }
            catch (Exception ex)
            {
                ErrorUtil eutil = new ErrorUtil();
                eutil.LogException(_cutil.UserID, "Users InitializeData", "", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void TreeEvents()
        {
            switch (_selectednode.Level)
            {
                case 0:
                    // root node level - do nothing
                    break;

                case 1:
                    if (_selectednode.Nodes.Count == 0)
                    {
                        // lastname initial level, get Users
                        PopulateUsers();
                    }
                    break;

                case 2:
                    // User level, populate user versions grid
                    PopulateUserVersions();
                    break;
            }
        }

        /// <summary>
        /// populates the tree with lastname initials of all actual users in the system
        /// </summary>
        private void PopulateUserTree()
        {
            // populate the top level of the tree
            Dictionary<string, string> paramList = new Dictionary<string, string>();

            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.GetLastNameLetters.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                string tmpdata = _cutil.Result;
                tmpdata = tmpdata.Replace("<![CDATA[", "");
                tmpdata = tmpdata.Replace("]]>", "");

                StringReader sr = new StringReader(tmpdata);
                DataTable userlist = new DataTable();
                userlist.ReadXml(sr);

                if (userlist.Rows.Count > 0)
                {
                    trvUsers.BeginUpdate();
                    trvUsers.Nodes.Clear();

                    // populate root node of API tree
                    UserTreeNode utnr = new UserTreeNode();
                    utnr.UserName = "Jigsaw Users";
                    utnr.FirstName = "Root";
                    utnr.LastName = "Root";

                    TreeNode tnr = new TreeNode();
                    tnr.Text = "Jigsaw Users";
                    tnr.ImageIndex = 2;
                    tnr.SelectedImageIndex = 2;
                    tnr.Tag = utnr;

                    trvUsers.Nodes.Add(tnr);

                    // populate top level of API tree
                    foreach (DataRow dr in userlist.Rows)
                    {
                        TreeNode tn = new TreeNode();
                        tn.Text = dr["Initial"].ToString().ToUpper();
                        tn.ImageIndex = 0;
                        tn.SelectedImageIndex = 0;
                        
                        tnr.Nodes.Add(tn);
                    }

                    trvUsers.EndUpdate();
                }
            }

        }

        /// <summary>
        /// click on lastname initial letter populates all users with that lastname initial
        /// </summary>
        public void PopulateUsers()
        {
            // get info from the selected tree node
            string initial = _selectednode.Text;

            Dictionary<string, string> paramList = new Dictionary<string, string>();
            paramList.Add("Initial", initial);

            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.GetLastInitialUsers.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                string tmpdata = _cutil.Result;
                tmpdata = tmpdata.Replace("<![CDATA[", "");
                tmpdata = tmpdata.Replace("]]>", "");

                StringReader sr = new StringReader(tmpdata);
                DataTable methlist = new DataTable();
                methlist.ReadXml(sr);

                if (methlist.Rows.Count > 0)
                {
                    trvUsers.BeginUpdate();

                    foreach (DataRow dr in methlist.Rows)
                    {
                        UserTreeNode utn = new UserTreeNode();
                        utn.FirstName = dr["FirstName"].ToString();
                        utn.LastName = dr["LastName"].ToString();
                        utn.UserName = dr["UserName"].ToString();
                        utn.GID = dr["GlobalID"].ToString();

                        TreeNode tn = new TreeNode();
                        tn.Text = dr["LastName"].ToString() + ", " + dr["FirstName"].ToString();
                        tn.ImageIndex = 1;
                        tn.SelectedImageIndex = 1;
                        tn.Tag = utn;
                        tn.ContextMenu = ctxmUser;

                        _selectednode.Nodes.Add(tn);
                    }

                    trvUsers.EndUpdate();
                    trvUsers.Refresh();
                    trvUsers.SelectedNode.Expand();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void PopulateUserVersions()
        {
            // get info from the selected tree node and tag object
            UserTreeNode selectedTag = (UserTreeNode)_selectednode.Tag;
            lblSelectedUser.Text = "Selected User: " + selectedTag.UserName;
            Dictionary<string, string> paramList = new Dictionary<string, string>();
            paramList.Add("UserID", selectedTag.GID);

            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.GetUserVersions.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                string tmpdata = _cutil.Result;
                tmpdata = tmpdata.Replace("<![CDATA[", "");
                tmpdata = tmpdata.Replace("]]>", "");

                StringReader sr = new StringReader(tmpdata);
                DataTable verlist = new DataTable();
                verlist.ReadXml(sr);

                if (verlist.Rows.Count > 0)
                {
                    dgvUserAccounts.DataSource = verlist;
                    PopulateUserForm();
                }
                else
                {
                    dgvUserAccounts.DataSource = null;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void PopulateUserForm()
        {
            txtPassword.ReadOnly = true;
            txtPassword.BackColor = Color.WhiteSmoke;

            txtGlobalID.Text = dgvUserAccounts.SelectedRows[0].Cells["GlobalID"].Value.ToString();
            txtFirstName.Text = dgvUserAccounts.SelectedRows[0].Cells["FirstName"].Value.ToString();
            txtLastName.Text = dgvUserAccounts.SelectedRows[0].Cells["LastName"].Value.ToString();
            txtUserName.Text = dgvUserAccounts.SelectedRows[0].Cells["UserName"].Value.ToString();
            txtPassword.Text = dgvUserAccounts.SelectedRows[0].Cells["Password"].Value.ToString();
            txtEmail.Text = dgvUserAccounts.SelectedRows[0].Cells["Email"].Value.ToString();
            dtpExpiration.Value = Convert.ToDateTime(dgvUserAccounts.SelectedRows[0].Cells["Expiration"].Value.ToString());
            rtbGroupAccess.Text = dgvUserAccounts.SelectedRows[0].Cells["DataAccessSummary"].Value.ToString();
            rtbMethodAccess.Text = dgvUserAccounts.SelectedRows[0].Cells["MethodAccessSummary"].Value.ToString();

            btnSave.Enabled = true;
            btnDelete.Enabled = true;

            string rowstate = dgvUserAccounts.SelectedRows[0].Cells["RowState"].Value.ToString();
            if (rowstate != "Active")
            {
                btnRollback.Enabled = true;
                btnDelete.Enabled = false;
            }
            else
            {
                btnRollback.Enabled = false;
                btnDelete.Enabled = true;
            }
        }

        /// <summary>
        /// sets selected node on mousedown so right click context menus know which treenode was right-clicked
        /// </summary>
        private void trvUsers_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                var node = trvUsers.HitTest(e.X, e.Y).Node;
                trvUsers.SelectedNode = node;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void trvUsers_Click(object sender, EventArgs e)
        {
            //try
            //{
            //    ClearUsersForm();

            //    // assign the selected node
            //    _selectednode = trvUsers.SelectedNode;

            //    TreeEvents();
            //}
            //catch (Exception ex)
            //{
            //    ErrorUtil eutil = new ErrorUtil();
            //    eutil.LogException(_cutil.UserID, "Users trvUsers_AfterSelect", "", ex);
            //}
        }

        /// <summary>
        /// 
        /// </summary>
        private void trvUsers_AfterSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                ClearUsersForm();

                // assign the selected node
                _selectednode = trvUsers.SelectedNode;

                TreeEvents();
            }
            catch (Exception ex)
            {
                ErrorUtil eutil = new ErrorUtil();
                eutil.LogException(_cutil.UserID, "Users trvUsers_AfterSelect", "", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void ClearUsersForm()
        {
            lblSelectedUser.Text = "Selected User:";
            dgvUserAccounts.DataSource = null;
            txtGlobalID.Text = "";
            txtFirstName.Text = "";
            txtLastName.Text = "";
            txtUserName.Text = "";
            txtPassword.Text = "";
            txtEmail.Text = "";
            dtpExpiration.Value = Convert.ToDateTime("1/1/2012");
            rtbGroupAccess.Text = "";
            rtbMethodAccess.Text = "";

            btnSave.Enabled = false;
            btnDelete.Enabled = false;
            btnRollback.Enabled = false;
        }

        /// <summary>
        /// 
        /// </summary>
        private void btnNew_Click(object sender, EventArgs e)
        {
            PopulateUserTree();
            ClearUsersForm();
            dtpExpiration.Value = DateTime.Now.AddDays(365);
            txtPassword.ReadOnly = false;
            txtPassword.BackColor = Color.White;
            btnSave.Enabled = true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (ValidateData())
            {
                string action = "";
                Dictionary<string, string> paramList = new Dictionary<string, string>();
                paramList.Add("FirstName", txtFirstName.Text);
                paramList.Add("LastName", txtLastName.Text);
                paramList.Add("UserName", txtUserName.Text);
                paramList.Add("Password", _cutil.PasswordHash(txtUserName.Text, txtPassword.Text));
                paramList.Add("Email", txtEmail.Text);
                paramList.Add("Expiration", dtpExpiration.Value.ToString());
                paramList.Add("MethodAccessSummary", rtbMethodAccess.Text);
                paramList.Add("DataAccessSummary", rtbGroupAccess.Text);

                string encryptedinput = "";
                if (txtGlobalID.Text.Length > 0)
                {
                    // update existing record
                    paramList.Add("GlobalID", txtGlobalID.Text);
                    encryptedinput = _cutil.BuildMessageXML("SystemAdmin.SaveUserAccount.Base", paramList, true);
                }
                else
                {
                    // insert new record
                    paramList.Add("GlobalID", _cutil.GetNewID());
                    encryptedinput = _cutil.BuildMessageXML("SystemAdmin.NewUserAccount.Base", paramList, true);
                    action = "New";
                }

                string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

                EncryptUtil eutil = new EncryptUtil();
                _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

                if (_cutil.ResponseCode == "Success")
                {
                    ClearUsersForm();
                    if (action == "New")
                    {
                        PopulateUserTree();
                    }
                    else
                    {
                        TreeEvents();
                    }
                }
                else
                {
                    MessageBox.Show(_cutil.Result);
                }
            }
            else
            {
                MessageBox.Show("You must provide a value for all required fields.", "Data Validation");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (ValidateData())
            {
                Dictionary<string, string> paramList = new Dictionary<string, string>();
                paramList.Add("GlobalID", txtGlobalID.Text);
                paramList.Add("FirstName", txtFirstName.Text);
                paramList.Add("LastName", txtLastName.Text);
                paramList.Add("UserName", txtUserName.Text);
                paramList.Add("Password", _cutil.PasswordHash(txtUserName.Text, txtPassword.Text));
                paramList.Add("Email", txtEmail.Text);
                paramList.Add("Expiration", dtpExpiration.Value.ToString());
                paramList.Add("MethodAccessSummary", rtbMethodAccess.Text);
                paramList.Add("DataAccessSummary", rtbGroupAccess.Text);

                string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.DeleteUserAccount.Base", paramList, true);
                string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

                EncryptUtil eutil = new EncryptUtil();
                _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

                if (_cutil.ResponseCode == "Success")
                {
                    ClearUsersForm();
                    PopulateUserTree();
                }
                else
                {
                    MessageBox.Show(_cutil.Result);
                }
            }
            else
            {
                MessageBox.Show("You must provide a value for all required fields.", "Data Validation");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void btnRollback_Click(object sender, EventArgs e)
        {
            if (ValidateData())
            {
                Dictionary<string, string> paramList = new Dictionary<string, string>();
                paramList.Add("GlobalID", txtGlobalID.Text);
                paramList.Add("FirstName", txtFirstName.Text);
                paramList.Add("LastName", txtLastName.Text);
                paramList.Add("UserName", txtUserName.Text);
                paramList.Add("Password", _cutil.PasswordHash(txtUserName.Text, txtPassword.Text));
                paramList.Add("Email", txtEmail.Text);
                paramList.Add("Expiration", dtpExpiration.Value.ToString());
                paramList.Add("MethodAccessSummary", rtbMethodAccess.Text);
                paramList.Add("DataAccessSummary", rtbGroupAccess.Text);

                string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.SaveUserAccount.Base", paramList, true);
                string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

                EncryptUtil eutil = new EncryptUtil();
                _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

                if (_cutil.ResponseCode == "Success")
                {
                    ClearUsersForm();
                    PopulateUserTree();
                }
                else
                {
                    MessageBox.Show(_cutil.Result);
                }
            }
            else
            {
                MessageBox.Show("You must provide a value for all required fields.", "Data Validation");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void btnRefreshTree_Click(object sender, EventArgs e)
        {
            PopulateUserTree();
            ClearUsersForm();
        }

        /// <summary>
        /// 
        /// </summary>
        private void dgvUserAccounts_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            PopulateUserForm();
        }


        /// <summary>
        /// will not enable the save button unless all required fields have values
        /// </summary>
        private bool ValidateData()
        {
            bool isValid = true;

            if (txtFirstName.Text == "") isValid = false;
            if (txtLastName.Text == "") isValid = false;
            if (txtUserName.Text == "") isValid = false;
            if (txtPassword.Text == "") isValid = false;
            if (txtEmail.Text == "") isValid = false;
            DateTime currentdate = DateTime.Now;
            if (dtpExpiration.Value < currentdate) isValid = false;

            return isValid;
        }

        /// <summary>
        /// 
        /// </summary>
        private void dtpExpiration_ValueChanged(object sender, EventArgs e)
        {
            bool valid = ValidateData();
            if (valid)
            {
                btnSave.Enabled = true;
            }
            else
            {
                btnSave.Enabled = false;
            }
        }


    }


    public class UserTreeNode
    {
        private string _username = "";
        private string _lastname = "";
        private string _firstname = "";
        private string _gid = "";

        public UserTreeNode()
        {

        }

        public string UserName
        {
            get { return _username; }
            set { _username = value; }
        }

        public string LastName
        {
            get { return _lastname; }
            set { _lastname = value; }
        }

        public string FirstName
        {
            get { return _firstname; }
            set { _firstname = value; }
        }

        public string GID
        {
            get { return _gid; }
            set { _gid = value; }
        }
    }


    /// <summary>
    /// 
    /// </summary>
    public class UserUpdateEventArgs : System.EventArgs
    {
        public UserUpdateEventArgs()
        {

        }
    }
}
